﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Licenta_Stomatologie.Forms
{
    public partial class Diagnostic : Form
    {
        private List<Point[]> polygons;
        private Point[] locations;
        private int hovered;
        private int selected;
        private int pacientId;

        private int[] diseases;
        private PictureBox[] dintiafectati;

        private String[] boli = new String[] {"Abces dentar","Abrazie","Anodontie","Eroziune"};

        public Diagnostic(int pid)
        {
            hovered = 0;
            selected = 0;

            Point[] d1  = new Point[] { new Point(25, 112), new Point(49, 118), new Point(43, 159), new Point(15, 153) };
            Point[] d2  = new Point[] { new Point(45, 69), new Point(63, 78), new Point(50, 111), new Point(27, 101) };
            Point[] d3  = new Point[] { new Point(55, 46), new Point(79, 53), new Point(72, 72), new Point(56, 69) };
            Point[] d4  = new Point[] { new Point(66, 36), new Point(92, 50), new Point(92, 22) };
            Point[] d5  = new Point[] { new Point(97, 20), new Point(117, 13), new Point(124, 19), new Point(110, 43) };
            Point[] d6  = new Point[] { new Point(130, 19), new Point(136, 13), new Point(158, 19), new Point(144, 43) };
            Point[] d7  = new Point[] { new Point(159, 22), new Point(186, 37), new Point(161, 49) };
            Point[] d8  = new Point[] { new Point(178, 47), new Point(199, 45), new Point(198, 71), new Point(176, 68) };
            Point[] d9  = new Point[] { new Point(193, 79), new Point(209, 70), new Point(228, 99), new Point(205, 110) };
            Point[] d10 = new Point[] { new Point(205, 118), new Point(226, 113), new Point(240, 152), new Point(213, 160) };
            Point[] d11 = new Point[] { new Point(240, 185), new Point(221, 172), new Point(208, 178), new Point(204, 216), new Point(227, 221) };    
            Point[] d12 = new Point[] { new Point(227, 240), new Point(216, 222), new Point(202, 225), new Point(192, 257), new Point(210, 264) };
            Point[] d13 = new Point[] { new Point(199, 288), new Point(196, 263), new Point(180, 264), new Point(176, 284) };
            Point[] d14 = new Point[] { new Point(162, 284), new Point(186, 298), new Point(162, 311) };
            Point[] d15 = new Point[] { new Point(140, 291), new Point(154, 314), new Point(131, 315) };
            Point[] d16 = new Point[] { new Point(124, 317), new Point(94, 316), new Point(109, 292) };
            Point[] d17 = new Point[] { new Point(89, 308), new Point(87, 282), new Point(66, 294) };
            Point[] d18 = new Point[] { new Point(74, 279), new Point(52, 283), new Point(52, 263), new Point(65, 259) };
            Point[] d19 = new Point[] { new Point(56, 253), new Point(40, 261), new Point(23, 233), new Point(39, 218), new Point(54, 229) };
            Point[] d20 = new Point[] { new Point(23, 218), new Point(43, 212), new Point(39, 174), new Point(25, 172), new Point(12, 182) };

            polygons = new List<Point[]>(){d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20};


            locations = new Point[] {
                new Point(32, 135),
                new Point(45, 88),
                new Point(65, 58),
                new Point(84, 35),
                new Point(110, 26),
                new Point(146, 26),
                new Point(170, 35),
                new Point(188, 57),
                new Point(211, 88),
                new Point(222, 135),
                new Point(222, 197),
                new Point(209, 243),
                new Point(188, 274),
                new Point(170, 296),
                new Point(144, 305),
                new Point(110, 306),
                new Point(82, 296),
                new Point(65, 275),
                new Point(43, 244),
                new Point(33, 197)
            };

            InitializeComponent();

            pictureBox2.Parent = pictureBox1;
            pictureBox2.BackColor = Color.Transparent;

            pacientId = pid;

            dintiafectati = new PictureBox[21];
            int i;
            for (i = 1; i <= 20; i++)
            {
                dintiafectati[i] = new PictureBox();
                dintiafectati[i].Image = Properties.Resources.damage;
                dintiafectati[i].Visible = false;
                dintiafectati[i].Parent = pictureBox1;
                dintiafectati[i].BackColor = Color.Transparent;
                dintiafectati[i].Size = new Size(20, 20);

                Point l = locations[i - 1];
                l.X -= dintiafectati[i].Width / 2;
                l.Y -= dintiafectati[i].Height / 2;
                dintiafectati[i].Location = l;

                dintiafectati[i].Click += pictureBox1_Click_1;
            }

            diseases = getDiseases();
            for(i = 1; i <= 20; i++)
            {
                if (diseases[i] > 0)
                {
                    dintiafectati[i].Visible = true;
                }
            }

            initialiseTreatmentsTable();
        }

        private static bool IsInPolygon(Point[] poly, Point p)
        {
            Point p1, p2;
            bool inside = false;

            if (poly.Length < 3)
            {
                return inside;
            }

            var oldPoint = new Point(
                poly[poly.Length - 1].X, poly[poly.Length - 1].Y);

            for (int i = 0; i < poly.Length; i++)
            {
                var newPoint = new Point(poly[i].X, poly[i].Y);

                if (newPoint.X > oldPoint.X)
                {
                    p1 = oldPoint;
                    p2 = newPoint;
                }
                else
                {
                    p1 = newPoint;
                    p2 = oldPoint;
                }

                if ((newPoint.X < p.X) == (p.X <= oldPoint.X)
                    && (p.Y - (long)p1.Y) * (p2.X - p1.X)
                    < (p2.Y - (long)p1.Y) * (p.X - p1.X))
                {
                    inside = !inside;
                }

                oldPoint = newPoint;
            }

            return inside;
        }

        private void initialiseTreatmentsTable()
        {
            ProjectDBEntities db = new ProjectDBEntities();
            DataTable dt = new DataTable("previousTreatments");

            DataColumn[] cols = new DataColumn[] {new DataColumn("Dinte", typeof(int)), new DataColumn("Boala", typeof(String)), new DataColumn("Tratament",typeof(String)) };

            dt.Columns.AddRange(cols);

            IEnumerable<Afectiuni> aff = db.Afectiunis.Where(a => a.pacientId == pacientId && a.status == 1);

            foreach (Afectiuni af in aff)
            {
                dt.Rows.Add(af.teeth, boli[(int)af.disease], af.treatment);
            }

            if (dt.Rows.Count == 0)
            {
                dataGridView1.Visible = false;
            }
            else
            {
                dataGridView1.Visible = true;
                dataGridView1.DataSource = dt;
            }
        }

        private void pictureBox1_Click_1(object sender, EventArgs e)
        {
            selected = hovered;

            if (selected > 0)
            {
                Point l = locations[selected - 1];
                l.X -= pictureBox2.Width / 2;
                l.Y -= pictureBox2.Height / 2;
                pictureBox2.Location = l;
                pictureBox2.Visible = true;
                label1.Text = "Este selectat dintele: "+ Convert.ToString(selected);

                int disease = getDisease(selected);
                String treatment = getTreatment(selected);
                tboxTratament.Text = treatment;
                if (disease != -1)
                {
                    comboBox1.SelectedIndex = disease;
                }
                else
                {
                    comboBox1.SelectedIndex = -1;
                }
            }
            else
            {
                pictureBox2.Visible = false;
                label1.Text = "Niciun dinte nu este selectat";
                comboBox1.SelectedIndex = -1;
                tboxTratament.Text = "";
            }
        }

        private void pictureBox1_MouseMove_1(object sender, MouseEventArgs e)
        {
            int d = 0;

            foreach (Point[] poly in polygons)
            {
                d++;

                if (IsInPolygon(poly, e.Location))
                {
                    hovered = d;

                    return;
                }
            }

            hovered = 0;
        }

        // returns for each element from the vector (teeth) the disease
        // e.g. : d[1] => is the disease for teeth 1 (0 means no disease)
        private int[] getDiseases()
        {
            try
            {
                int[] v = new int[21];
                for (int i = 1; i < 21; i++)
                    v[i] = 0;

                ProjectDBEntities db = new ProjectDBEntities();

                IEnumerable<Afectiuni> affs = db.Afectiunis.Where(a => a.pacientId == pacientId && a.status == 0);

                foreach (Afectiuni aff in affs)
                {
                    v[(int)aff.teeth] = (int) aff.disease;
                }

                return v;
            }
            catch (Exception e)
            {
                int[] v = new int[21];
                for (int i = 1; i < 21; i++)
                    v[i] = 0;

                return v;
            }
        }

        private String getTreatment(int teeth)
        {
            ProjectDBEntities db = new ProjectDBEntities();

            try
            {
                Afectiuni af = db.Afectiunis.First(a => a.pacientId == pacientId && a.teeth == teeth && a.status == 0);

                if (af == null)
                {
                    return "";
                }
                return af.treatment.ToString();
            }
            catch (Exception e)
            {
                return "";
            }
        }

        private int getDisease(int teeth)
        {
            ProjectDBEntities db = new ProjectDBEntities();

            try
            {
                Afectiuni af = db.Afectiunis.First(a => a.pacientId == pacientId && a.teeth == teeth && a.status == 0);

                if (af == null)
                {
                    return -1;
                }
                return (int)af.disease;
            }
            catch (Exception e)
            {
                return -1;
            }
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex != -1 && selected != 0)
            {
                ProjectDBEntities db = new ProjectDBEntities();

                Afectiuni a = new Afectiuni();

                a.pacientId = pacientId;
                a.disease = comboBox1.SelectedIndex;
                a.teeth = selected;
                a.status = 0;
                a.treatment = tboxTratament.Text;

                db.Afectiunis.Add(a);

                db.SaveChanges();

                dintiafectati[selected].Visible = true;

                MessageBox.Show("Diagnosticare salvata cu succes");
            }
            else
            {
                MessageBox.Show("Trebuie sa selectati un dinte si o afectiune");
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex != -1 && selected != 0)
            {
                try
                {
                    ProjectDBEntities db = new ProjectDBEntities();

                    Afectiuni af = db.Afectiunis.First(a => a.pacientId == pacientId && a.teeth == selected);

                    af.status = 1;

                    db.SaveChanges();

                    dintiafectati[selected].Visible = false;

                    MessageBox.Show("Afectiune eliminata cu succes");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Afectiunea nu a putut fi eliminata. Nu exista o afectiune salvata pentru acest dinte");
                }
            }
            else
            {
                MessageBox.Show("Trebuie sa selectati un dinte");
            }
        }
    }
}
